package com.tenement.netty.Handler;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.tenement.entity.Chat;
import com.tenement.entity.ChatModel;
import com.tenement.enums.Command;
import com.tenement.netty.service.ChatHandlerService;
import com.tenement.netty.service.impl.*;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.concurrent.GlobalEventExecutor;
import lombok.extern.slf4j.Slf4j;
import java.sql.Timestamp;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;


@Slf4j
public class ChatHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {


    public static Map<String, Channel> privateChannel = new ConcurrentHashMap<>();
    public static ChannelGroup channelGroups = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);



    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        channelGroups.add(ctx.channel());
    }




    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.info("客服端断开连接："+ctx.channel().id()+"\t异常信息：" + cause.getMessage());
        String userIdToRemove = getKeyByValue(privateChannel, ctx.channel());
        if (userIdToRemove != null) {
            privateChannel.remove(userIdToRemove);
            log.info("移除了异常的通道，用户ID: " + userIdToRemove);
        }
        channelGroups.remove(ctx.channel());
        ctx.close();
    }


    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        log.info("客服端断开连接："+ctx.channel().id());
        String userIdToRemove = getKeyByValue(privateChannel, ctx.channel());
        if (userIdToRemove != null) {
            privateChannel.remove(userIdToRemove);
            log.info("移除了关闭通道的，用户ID: " + userIdToRemove);
        }
        channelGroups.remove(ctx.channel());
        ctx.close();
    }

    private <K, V> K getKeyByValue(Map<K, V> map, V value) {
        for (Map.Entry<K, V> entry : map.entrySet()) {
            if (Objects.equals(value, entry.getValue())) {
                return entry.getKey();
            }
        }
        return null; // 如果没有找到对应的Key则返回null
    }





    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, TextWebSocketFrame textWebSocketFrame) throws Exception {
        try {
            ChatModel chatModel = JSON.parseObject(textWebSocketFrame.text(),ChatModel.class);
            Chat chat = new Chat();
            ChatHandlerService chatHandler = getChatHandler(chatModel.getCmd());
            chatHandler.execute(chatModel,channelHandlerContext,privateChannel,channelGroups);
        }catch (JSONException e) {
            channelHandlerContext.channel().writeAndFlush(new TextWebSocketFrame(JSON.toJSONString(new ChatModel().setType((short)3).setMsg("数据格式错误").setSendTime(new Timestamp(new Date().getTime())))));
        }catch (NullPointerException e) {
            channelHandlerContext.channel().writeAndFlush(new TextWebSocketFrame(JSON.toJSONString(new ChatModel().setType((short)3).setMsg("数据为空").setSendTime(new Timestamp(new Date().getTime())))));
        }
    }

    private ChatHandlerService getChatHandler(int command) {
        Command cmd = Objects.requireNonNull(Command.match(command));
        switch (cmd) {
            case OFFLINE:
                return new OfflineServiceImpl();
            case CONNECT:
                return new ConnectServiceImpl();
            case PRIVATE:
                return new PrivateServiceImpl();
            case RADIO:
                return new RadioServiceImpl();
            case LINERADIO:
                return new LineRadioServiceImpl();
            case ACTIVE:
                return new ActiveServiceImpl();
            default:
                return new NoCmdServiceImpl();
        }
    }

}
